package com.ys.erp.gateway.filter;

import com.alibaba.fastjson2.JSONObject;
import com.ys.erp.common.enums.RedisKey;
import com.ys.erp.common.json.YsJSONUtil;
import com.ys.erp.framework.response.AbstractResponseCode;
import com.ys.erp.gateway.config.GatewayErrHandler;
import com.ys.erp.gateway.config.ProjectProperties;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.RequestPath;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author lwj
 * @date 2024/8/24
 */
@Component
@Slf4j
public class RightsFilter implements GlobalFilter, Ordered {

    private final ProjectProperties projectProperties;

    private final RedisTemplate<String, String> redisTemplate;

    @Lazy
    public RightsFilter(ProjectProperties projectProperties, RedisTemplate<String, String> redisTemplate) {
        this.projectProperties = projectProperties;
        this.redisTemplate = redisTemplate;
    }

    @SneakyThrows
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getHeaders().getFirst("token");
        RequestPath path = exchange.getRequest().getPath();
        log.info("path:{}", path);
        List<String> whitePath = projectProperties.getWhitePath();
        if (!ObjectUtils.isEmpty(whitePath) && whitePath.contains(path.toString())) {
            return chain.filter(exchange);
        }
        // 执行权限校验逻辑
        exchange.getResponse().setStatusCode(HttpStatus.OK);
        exchange.getResponse().getHeaders().set("Content-Type", "application/json");
        if (ObjectUtils.isEmpty(token)) {
            // 权限校验失败，构建并返回错误响应
            return chain.filter(exchange);
        }
        String empDetailStr = redisTemplate.opsForValue().get(RedisKey.Enums.EMP_LOGIN_FLAG.getKey()+token);
        if (ObjectUtils.isEmpty(empDetailStr)) {
            return chain.filter(exchange);
        }
        //查询所有权限
        String s = redisTemplate.opsForValue().get(RedisKey.Enums.ALL_RIGHT_FLAG.getKey());
        Map<String, String> urlAndRightMap = YsJSONUtil.toMap(Objects.requireNonNull(JSONObject.parse(s)));
        // 处理查询结果
        if (!urlAndRightMap.containsKey(path.toString())) {
            return chain.filter(exchange);
        }
        //请求地址做了权限，校验
        String rightFlag = urlAndRightMap.get(path.toString());
        JSONObject empDetailObj = JSONObject.parseObject(empDetailStr);
        if (!empDetailObj.getJSONArray("rightFlags").contains(rightFlag)) {
            return GatewayErrHandler.throwException(exchange, AbstractResponseCode.RIGHT_ERROR);
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 1;
    }
}
